#ifndef STRINGID_H
#define STRINGID_H

#include "crc32.h"

#include <iostream>

namespace num
{

class StringID
{
public:
    StringID ( ) : m_ID ( 0 ) { }

    StringID ( const StringID & sid ) : m_ID ( sid.m_ID ) { }

    StringID ( unsigned long id ) : m_ID( id ) { }

    StringID ( const std::string & str ) : 
    m_ID ( num::CRC32::Instance().StrCRC ( str.c_str ( ), true ) ) { }

    ~StringID ( ) { }

    StringID  & operator= ( const StringID & sid ) { m_ID = sid.m_ID; 
                                                     return *this; }

    bool operator== ( const StringID & sid ) { return sid.m_ID == m_ID; }
    bool operator!= ( const StringID & sid ) { return sid.m_ID != m_ID; }
    bool operator<  ( const StringID & sid ) { return sid.m_ID < m_ID; }

    void SetID( unsigned long id ) { m_ID = id; }
    unsigned long GetID( ) { return m_ID; }

    bool IsValid ( ) { return m_ID != 0; }
    unsigned long GetNumeric ( ) { return m_ID; }

    static unsigned long StringToID ( const std::string & str ) 
    {
        return CRC32::Instance ( ).StrCRC ( str.c_str ( ), true );
    }

private:
    friend std::ostream & operator<<( std::ostream & os, const StringID & sid );

    friend bool operator< ( const StringID & sid1, const StringID & sid2 );

    unsigned long m_ID;

};  // class ObjectID

inline std::ostream & operator<<( std::ostream & os, const StringID & obj )
{
    return os << obj.m_ID << std::endl;
}

inline bool operator<( const StringID & sid1, const StringID & sid2 )
{
    return sid1.m_ID < sid2.m_ID;
}

}

#endif  
